import type { ReactElement, ReactNode } from 'react';
import { getIntl, getLocale, useIntl } from 'umi';
import type { MessageDescriptor, IntlShape } from 'react-intl';
import type { PrimitiveType, FormatXMLElementFn } from 'intl-messageformat';

const formatMessage = (msg: string, values: Record<string, unknown> = {}) =>
  msg.replace(/\{(\w+)\}/g, (s) => {
    const key = s.slice(1, s.length - 1);
    return String(values[key] ?? s);
  });
export interface ZuoyDescriptor extends MessageDescriptor {
  value?: string | number;
}

export type Values = Record<
  string,
  PrimitiveType | ReactElement | FormatXMLElementFn
>;

const zuoyIntl = (
  intl: IntlShape,
  zuoyDescriptor: string | ZuoyDescriptor,
  values?: Values,
  env: string = ENV,
) => {
  let params = {};
  let devValue = '';
  if (typeof zuoyDescriptor === 'string') {
    params = { id: zuoyDescriptor };
    devValue = formatMessage(zuoyDescriptor, values);
  } else {
    const { value, ...descriptor } = zuoyDescriptor;
    const valStr = `${value}`;
    params = { id: valStr, ...descriptor };
    devValue = formatMessage(valStr, values);
  }
  return env === 'prod' ? intl.formatMessage(params, values) : devValue;
};

// umi的getIntl中获取intl，封装z函数
export function zuoyFunctionZ(
  zuoyDescriptor: string | ZuoyDescriptor,
  values?: Record<string, PrimitiveType>,
): string;

export function zuoyFunctionZ(
  zuoyDescriptor: string | ZuoyDescriptor,
  values?: Values,
) {
  const intl = getIntl(getLocale());
  return zuoyIntl(intl, zuoyDescriptor, values);
}

export function useZuoyIntl(env: 'dev' | 'prod' | string = ENV) {
  const intl = useIntl();
  function zuoyIntlHook(
    zuoyDescriptor: string | ZuoyDescriptor,
    values?: Record<string, PrimitiveType>,
  ): string;
  function zuoyIntlHook(
    zuoyDescriptor: string | ZuoyDescriptor,
    values?: Values,
  ): ReactNode[];
  function zuoyIntlHook(
    zuoyDescriptor: string | ZuoyDescriptor,
    values?: Values,
  ) {
    return zuoyIntl(intl, zuoyDescriptor, values, env);
  }
  return zuoyIntlHook;
}
